local TIGERSFURY, MANGLE, SAVAGEROAR, RAKE, RIP, MAUL, FAERIEFIRE, BEARMANGLE, LACERATE, DEMOROAR = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

-- change order of icons here
local crhCatFrames = {TIGERSFURY, SAVAGEROAR, MANGLE, RAKE, RIP}
local crhBearFrames = {MAUL, FAERIEFIRE, BEARMANGLE, LACERATE, DEMOROAR}

local frames = {
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent)
}

local events = {
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent),
	CreateFrame("Frame", nil, UIParent)
}

local textures = {
	"Interface\\AddOns\\CatRotationHelper\\TigersFury.tga",
	"Interface\\AddOns\\CatRotationHelper\\Mangle.tga",
	"Interface\\AddOns\\CatRotationHelper\\SavageRoar.tga",
	"Interface\\AddOns\\CatRotationHelper\\Rake.tga",
	"Interface\\AddOns\\CatRotationHelper\\Rip.tga",
	"Interface\\AddOns\\CatRotationHelper\\Maul.tga",
	"Interface\\AddOns\\CatRotationHelper\\FaerieFire.tga",
	"Interface\\AddOns\\CatRotationHelper\\Mangle.tga",
	"Interface\\AddOns\\CatRotationHelper\\Lacerate.tga",
	"Interface\\AddOns\\CatRotationHelper\\DemoRoar.tga"
}

local blueTextures = {
	"Interface\\AddOns\\CatRotationHelper\\TigersFury-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Mangle-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\SavageRoar-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Rake-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Rip-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Maul-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\FaerieFire-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Mangle-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\Lacerate-Blue.tga",
	"Interface\\AddOns\\CatRotationHelper\\DemoRoar-Blue.tga"
}

--                      r    g    b    a
local fadedcolor   = {0.35,0.35,0.35,0.70};
local upcolor      = {1.00,1.00,1.00,1.00};

-- state variables
local inCatForm = false;
local inBearForm = false;
local enemyTarget = false;
local showCat = false;
local showBear = false;
local clearCast = false;
local unlocked = false;

-- eventframe variables
local eventList = {}
local eventTimers = {}

-- saved variables
crhScale = 1;
crhEventScale = 1.15;
crhCp = true;
crhLacCounter = true;
crhEnableClearcast = true;
crhShowBear = true;
crhShowCat = true;
crhEventAngle = 0;
crhMainAngle = 0;

crhShowCatFaerieFire = true;
crhShowCatBerserk = true;
crhShowBearBerserk = true;
crhShowPredatorsSwiftness = true;
crhShowSurvivalInstincts = true;
crhShowBarkskin = true;

--bugfix
local function crhSpellName(id)
	local name = GetSpellInfo(id)
	return name
end

local function crhTargetHasDebuff(name)
	local buffName = UnitDebuff("target", name)
	return (buffName ~= nil)
end

local function CatRotationHelperFormatTime(time)
	if (time >= 60) then
		return ceil(time / 60).."m";
	elseif(time >= 1) then
		return floor(time);
	else
		return "."..floor(time*10);		
	end
end

function CatRotationHelperUpdateEverything()
	if(GetShapeshiftForm() == 3 and crhShowCat) then
		inCatForm = true
	elseif(GetShapeshiftForm() == 1 and crhShowBear) then
		inBearForm = true
	end

	if(UnitExists("target") and UnitCanAttack("player", "target") and not UnitIsDead("target")) then
		enemyTarget = true
	end

	if(enemyTarget and inCatForm) then
		CatRotationHelperShowCat();
		CatRotationHelperCheckCatBuffs();
		CatRotationHelperCheckCatDebuffs();
		CatRotationHelperCheckCatCooldown()
		CatRotationHelperSetCatCP(GetComboPoints("player"));
		CatRotationHelperUpdateEvents()
	elseif(enemyTarget and inBearForm) then
       	CatRotationHelperShowBear();
		CatRotationHelperCheckBearBuffs()
       	CatRotationHelperCheckBearDebuffs();
		CatRotationHelperCheckBearCooldown();	
		CatRotationHelperUpdateEvents()
	end

end

function CatRotationHelperUnlock()
	CatRotationHelperHeader:Show();
	CatRotationHelperEvents:Show();
	CatRotationHelperLockFrame:Show();
	HideUIPanel(InterfaceOptionsFrame)
	unlocked = true;
	
	CatRotationHelperInstaHideAll()
	
	for i=1, #crhCatFrames do
		local frame = frames[crhCatFrames[i]]
		
		frame:Show();
		frame:SetAlpha(1);
		frame.icon:SetVertexColor(upcolor[1], upcolor[2], upcolor[3], upcolor[4]);
		frame.icon:SetTexture(textures[crhCatFrames[i]])
	end

	eventList[1] = "Interface\\AddOns\\CatRotationHelper\\Berserk.tga"
	eventList[2] = "Interface\\AddOns\\CatRotationHelper\\FaerieFire.tga"
	eventList[3] = "Interface\\AddOns\\CatRotationHelper\\PredatoryStrikes.tga"
	
	for i=1, #events do
		events[i]:Show()
		events[i]:SetAlpha(1)
		events[i].fading = false
		events[i].startTime = nil
		events[i].countframe:Hide();
		events[i].countframe.endTime = nil;
		events[i]:SetScript("OnUpdate",nil)	
		events[i].icon:SetTexture(eventList[i])
	end

end

function CatRotationHelperLock()
	if(not unlocked) then
		return
	end
	
	CatRotationHelperHeader:Hide();
	CatRotationHelperEvents:Hide();
	CatRotationHelperLockFrame:Hide();
		
	unlocked = false;
	clearCast = false;
	
	for i=1, #frames do
		local frame = frames[i]
		
		frame:Hide()
		frame.icon:SetVertexColor(fadedcolor[1], fadedcolor[2], fadedcolor[3], fadedcolor[4]);
		frame.effectframe.effecticon:SetTexture(textures[i])
		frame.icon:SetTexture(textures[i])
		frame.countframe.durtext:SetTextColor(1.00, 1.00, 0.00);
		frame.countframe:Hide();
		frame.cpicon:SetTexture("Interface\\AddOns\\CatRotationHelper\\Cp.tga")
	end
	
	for i=1, #events do
		events[i]:Hide()
	end

	CatRotationHelperUpdateEverything()
end

-- shows num combo point circles using frames in framesTable
local function CatRotationHelperSetCPEffects(framesTable, num)
	for i=1, #framesTable do
		local frame = frames[framesTable[i]]
	
		if(i <= num) then
			if(not frame.hascp) then
				if(clearCast) then
					frame.countframe.durtext:SetTextColor(0.40, 0.70, 0.95);				
				else
					frame.countframe.durtext:SetTextColor(0.90, 0.70, 0.00);
				end
				frame.hascp = true;
				frame.cpframe:Show()
				frame.cpframe:SetScript("OnUpdate", CatRotationHelperCpEffect)
				frame.cpframe.startTime = GetTime()
				frame.cpframe.reverse = false
			end
		else
			if(frame.hascp) then
				if(clearCast) then
					frame.countframe.durtext:SetTextColor(0.50, 0.85, 1.00);				
				else
					frame.countframe.durtext:SetTextColor(1.00, 1.00, 0.00);
				end
				frame.hascp = false;
				frame.cpframe:SetScript("OnUpdate", CatRotationHelperCpEffect)
				frame.cpframe.startTime = GetTime()
				frame.cpframe.reverse = true
			else
				return;
			end
		end
	end
end	

function CatRotationHelperSetCatCP(num)
	if(not crhCp) then return; end
	
	CatRotationHelperSetCPEffects(crhCatFrames, num);
end

function CatRotationHelperSetBearCP(num)
	if(not crhLacCounter) then return; end
	
	CatRotationHelperSetCPEffects(crhBearFrames, num);
end


-- show all frames in frameTable
local function CatRotationHelperShowByFrame(frameTable)	
	--if interrupting previous fade, hide frames
	for i=1, #frames do
		frames[i]:Hide();
	end

	for i=1, #frameTable do
		frames[frameTable[i]]:Show();
	end
	
	-- fade effect
	CatRotationHelperFadeFrame:Show();
	CatRotationHelperFadeFrame.fading = false;
	CatRotationHelperFadeFrame.startTime = GetTime();
end

function CatRotationHelperShowCat()
	if(showCat) then return; end
	showCat = true;

	CatRotationHelperShowByFrame(crhCatFrames);
end

function CatRotationHelperShowBear()
	if(showBear) then return; end
	showBear = true;

	CatRotationHelperShowByFrame(crhBearFrames);
end

function CatRotationHelperUpdateFrame(self, endTime)
    if(not self.counting or endTime ~= self.countframe.endTime) then
    	-- new buff applied
		self.counting = true
		self.icon:SetVertexColor(upcolor[1], upcolor[2], upcolor[3], upcolor[4])

    	self.countframe.endTime = endTime
    	self.countframe:Show()

		self.effectframe:Show()
		self.effectframe.startTime = GetTime()
	end
end

function CatRotationFrameStopCounter(self)
	if(self.counting) then
		self.counting = false
		self.countframe:Hide();
		self.countframe.endTime = nil;

		self.icon:SetVertexColor(fadedcolor[1], fadedcolor[2], fadedcolor[3], fadedcolor[4]);

		self.effectframe:Show();
		self.effectframe.startTime = GetTime()
	end
end

function CatRotationFrameSetMainScale()
	for i=1, #frames do
		frames[i]:SetScale(crhScale);
		frames[i].parentFrame:SetScale(crhScale);
	end
	
	CatRotationHelperHeader:SetScale(crhScale);
end

function CatRotationFrameSetEventScale()
	for i=1, #events do
		events[i]:SetScale(crhEventScale);
		events[i].parentFrame:SetScale(crhEventScale);
	end

	CatRotationHelperEvents:SetScale(crhEventScale);
end

-- rotate main frame
function CatRotationHelperMainOnClick()

	if(crhMainAngle == 270) then
		crhMainAngle = 0
	else
		crhMainAngle = crhMainAngle + 90
	end
	
	CatRotationFrameSetMainStyle()
end

function CatRotationFrameSetMainStyle()
	for i=1, #frames do
		frames[i].parentFrame:ClearAllPoints()
	end

	if(crhMainAngle == 0) then
		CatRotationHelperHeader:SetHeight(36)
		CatRotationHelperHeader:SetWidth(176)

		frames[crhCatFrames[1]].parentFrame:SetPoint("TOPLEFT", CatRotationHelperHeader, "TOPLEFT", 3, -3);
		frames[crhBearFrames[1]].parentFrame:SetPoint("TOPLEFT", CatRotationHelperHeader, "TOPLEFT", 3, -3);

		frames[crhCatFrames[2]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[1]].parentFrame, "TOPRIGHT", 5, 0);
		frames[crhBearFrames[2]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[1]].parentFrame, "TOPRIGHT", 5, 0);

		frames[crhCatFrames[3]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[2]].parentFrame, "TOPRIGHT", 5, 0);
		frames[crhBearFrames[3]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[2]].parentFrame, "TOPRIGHT", 5, 0);

		frames[crhCatFrames[4]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[3]].parentFrame, "TOPRIGHT", 5, 0);
		frames[crhBearFrames[4]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[3]].parentFrame, "TOPRIGHT", 5, 0);

		frames[crhCatFrames[5]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[4]].parentFrame, "TOPRIGHT", 5, 0);
		frames[crhBearFrames[5]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[4]].parentFrame, "TOPRIGHT", 5, 0);
		
	elseif(crhMainAngle == 90) then
		CatRotationHelperHeader:SetHeight(176)
		CatRotationHelperHeader:SetWidth(36)
	
		frames[crhCatFrames[1]].parentFrame:SetPoint("BOTTOMLEFT", CatRotationHelperHeader, "BOTTOMLEFT", 3, 3);
		frames[crhBearFrames[1]].parentFrame:SetPoint("BOTTOMLEFT", CatRotationHelperHeader, "BOTTOMLEFT", 3, 3);

		frames[crhCatFrames[2]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhCatFrames[1]].parentFrame, "TOPLEFT", 0, 5);
		frames[crhBearFrames[2]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhBearFrames[1]].parentFrame, "TOPLEFT", 0, 5);

		frames[crhCatFrames[3]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhCatFrames[2]].parentFrame, "TOPLEFT", 0, 5);
		frames[crhBearFrames[3]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhBearFrames[2]].parentFrame, "TOPLEFT", 0, 5);

		frames[crhCatFrames[4]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhCatFrames[3]].parentFrame, "TOPLEFT", 0, 5);
		frames[crhBearFrames[4]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhBearFrames[3]].parentFrame, "TOPLEFT", 0, 5);

		frames[crhCatFrames[5]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhCatFrames[4]].parentFrame, "TOPLEFT", 0, 5);
		frames[crhBearFrames[5]].parentFrame:SetPoint("BOTTOMLEFT", frames[crhBearFrames[4]].parentFrame, "TOPLEFT", 0, 5);
	
	elseif(crhMainAngle == 180) then
		CatRotationHelperHeader:SetHeight(36)
		CatRotationHelperHeader:SetWidth(176)
	
		frames[crhCatFrames[1]].parentFrame:SetPoint("TOPRIGHT", CatRotationHelperHeader, "TOPRIGHT", -3, -3);
		frames[crhBearFrames[1]].parentFrame:SetPoint("TOPRIGHT", CatRotationHelperHeader, "TOPRIGHT", -3, -3);

		frames[crhCatFrames[2]].parentFrame:SetPoint("TOPRIGHT", frames[crhCatFrames[1]].parentFrame, "TOPLEFT", -5, 0);
		frames[crhBearFrames[2]].parentFrame:SetPoint("TOPRIGHT", frames[crhBearFrames[1]].parentFrame, "TOPLEFT", -5, 0);

		frames[crhCatFrames[3]].parentFrame:SetPoint("TOPRIGHT", frames[crhCatFrames[2]].parentFrame, "TOPLEFT", -5, 0);
		frames[crhBearFrames[3]].parentFrame:SetPoint("TOPRIGHT", frames[crhBearFrames[2]].parentFrame, "TOPLEFT", -5, 0);

		frames[crhCatFrames[4]].parentFrame:SetPoint("TOPRIGHT", frames[crhCatFrames[3]].parentFrame, "TOPLEFT", -5, 0);
		frames[crhBearFrames[4]].parentFrame:SetPoint("TOPRIGHT", frames[crhBearFrames[3]].parentFrame, "TOPLEFT", -5, 0);

		frames[crhCatFrames[5]].parentFrame:SetPoint("TOPRIGHT", frames[crhCatFrames[4]].parentFrame, "TOPLEFT", -5, 0);
		frames[crhBearFrames[5]].parentFrame:SetPoint("TOPRIGHT", frames[crhBearFrames[4]].parentFrame, "TOPLEFT", -5, 0);
		
	else
		CatRotationHelperHeader:SetHeight(176)
		CatRotationHelperHeader:SetWidth(36)
		
		frames[crhCatFrames[1]].parentFrame:SetPoint("TOPLEFT", CatRotationHelperHeader, "TOPLEFT", 3, -3);
		frames[crhBearFrames[1]].parentFrame:SetPoint("TOPLEFT", CatRotationHelperHeader, "TOPLEFT", 3, -3);

		frames[crhCatFrames[2]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[1]].parentFrame, "BOTTOMLEFT", 0, -5);
		frames[crhBearFrames[2]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[1]].parentFrame, "BOTTOMLEFT", 0, -5);

		frames[crhCatFrames[3]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[2]].parentFrame, "BOTTOMLEFT", 0, -5);
		frames[crhBearFrames[3]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[2]].parentFrame, "BOTTOMLEFT", 0, -5);

		frames[crhCatFrames[4]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[3]].parentFrame, "BOTTOMLEFT", 0, -5);
		frames[crhBearFrames[4]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[3]].parentFrame, "BOTTOMLEFT", 0, -5);

		frames[crhCatFrames[5]].parentFrame:SetPoint("TOPLEFT", frames[crhCatFrames[4]].parentFrame, "BOTTOMLEFT", 0, -5);
		frames[crhBearFrames[5]].parentFrame:SetPoint("TOPLEFT", frames[crhBearFrames[4]].parentFrame, "BOTTOMLEFT", 0, -5);
	end

end

-- rotate event frame
function CatRotationHelperEventsOnClick()
	
	if(crhEventAngle == 270) then
		crhEventAngle = 0
	else
		crhEventAngle = crhEventAngle + 90
	end
	
	CatRotationFrameSetEventStyle()
end

function CatRotationFrameSetEventStyle()
	events[1].parentFrame:ClearAllPoints()
	events[2].parentFrame:ClearAllPoints()
	events[3].parentFrame:ClearAllPoints()

	if(crhEventAngle == 0) then
		CatRotationHelperEvents:SetHeight(36)
		CatRotationHelperEvents:SetWidth(105)
	
		events[1].parentFrame:SetPoint("TOPLEFT", CatRotationHelperEvents, "TOPLEFT", 3, -3);
		events[2].parentFrame:SetPoint("TOPLEFT", events[1].parentFrame, "TOPRIGHT", 4, 0);
		events[3].parentFrame:SetPoint("TOPLEFT", events[2].parentFrame, "TOPRIGHT", 4, 0);	
		
	elseif(crhEventAngle == 90) then
		CatRotationHelperEvents:SetHeight(105)
		CatRotationHelperEvents:SetWidth(36)

		events[1].parentFrame:SetPoint("BOTTOMLEFT", CatRotationHelperEvents, "BOTTOMLEFT", 3, 3);
		events[2].parentFrame:SetPoint("BOTTOMLEFT", events[1].parentFrame, "TOPLEFT", 0, 4);
		events[3].parentFrame:SetPoint("BOTTOMLEFT", events[2].parentFrame, "TOPLEFT", 0, 4);			

	elseif(crhEventAngle == 180) then
		CatRotationHelperEvents:SetHeight(36)
		CatRotationHelperEvents:SetWidth(105)
	
		events[1].parentFrame:SetPoint("TOPRIGHT", CatRotationHelperEvents, "TOPRIGHT", -3, -3);
		events[2].parentFrame:SetPoint("TOPRIGHT", events[1].parentFrame, "TOPLEFT", -4, 0);
		events[3].parentFrame:SetPoint("TOPRIGHT", events[2].parentFrame, "TOPLEFT", -4, 0);			
		
	else
		CatRotationHelperEvents:SetHeight(105)
		CatRotationHelperEvents:SetWidth(36)
		
		events[1].parentFrame:SetPoint("TOPLEFT", CatRotationHelperEvents, "TOPLEFT", 3, -3);
		events[2].parentFrame:SetPoint("TOPLEFT", events[1].parentFrame, "BOTTOMLEFT", 0, -4);
		events[3].parentFrame:SetPoint("TOPLEFT", events[2].parentFrame, "BOTTOMLEFT", 0, -4);	

	end
	
end

function CatRotationHelperInstaHideAll()
	local framesTable

	-- decide what frames to hide
	if(showBear) then
		showBear = false
		
		framesTable = crhBearFrames
		CatRotationHelperLacerateCounter:Hide()
		CatRotationHelperSetBearCP(0)
	elseif(showCat) then
		showCat = false
		
		
		framesTable = crhCatFrames
		CatRotationHelperSetCatCP(0)
	else
		return
	end
		
	-- interrupt previous fade
	CatRotationHelperFadeFrame:Hide();
		
	-- hide main frames
	for i=1, #framesTable do
		CatRotationFrameStopCounter(frames[framesTable[i]]);
		frames[framesTable[i]]:Hide()
	end
	
	-- hide events
	for i=1, #events do
		events[i]:Hide()
	end

end

function CatRotationHelperHideAll()
	local framesTable

	-- decide what frames to hide
	if(showBear) then
		showBear = false
		
		framesTable = crhBearFrames
		CatRotationHelperLacerateCounter:Hide()
		CatRotationHelperSetBearCP(0)
	elseif(showCat) then
		showCat = false
		
		framesTable = crhCatFrames
		CatRotationHelperSetCatCP(0)
	else
		return
	end
		
	-- stop running timers
	for i=1, #framesTable do
		CatRotationFrameStopCounter(frames[framesTable[i]]);
	end
	
	-- general fade animation
	CatRotationHelperFadeFrame:Show();
	CatRotationHelperFadeFrame.fading = true;
	CatRotationHelperFadeFrame.startTime = GetTime();
	
	-- hide events
	for i=1, #events do
		if(events[i]:IsVisible() and not events[i].fading) then
			events[i]:SetScript("OnUpdate",CatRotationHelperEventFadeFunc)
			events[i].fading = true
			events[i].startTime = GetTime()
		end
	end
end

-----------------------------
-- Cat - Main Frame Checks --
-----------------------------

function CatRotationHelperCheckCatBuffs()
	-- Savage Roar
	local name,_,_,_,_,_,expTime = UnitBuff("player", crhSpellName(52610)); -- Savage Roar
	if(name) then
		CatRotationHelperUpdateFrame(frames[SAVAGEROAR], expTime);
	else
		CatRotationFrameStopCounter(frames[SAVAGEROAR]);
	end
end

function CatRotationHelperCheckCatDebuffs()
	-- Mangle
	local name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(33876)); -- Mangle (Cat)
	if(name) then   
		CatRotationHelperUpdateFrame(frames[MANGLE], expTime);
	else
    	name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(33878)); -- Mangle (Bear) 
    	if(name) then
        	CatRotationHelperUpdateFrame(frames[MANGLE], expTime);
        else
    		name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(46857)); -- Trauma  
			if(name) then
        		CatRotationHelperUpdateFrame(frames[MANGLE], expTime);
    		else
				name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(30478)); -- Hemorrhage
				if(name) then
					CatRotationHelperUpdateFrame(frames[MANGLE], expTime);
				else
					CatRotationFrameStopCounter(frames[MANGLE]);
				end
    		end
    	end
	end

	-- Rip & Rake: Check for own debuffs only
	local rakeupdate, ripupdate;
	
	local i = 1
	local name, expTime, isMine
	
	repeat
		name,_,_,_,_,_,expTime,isMine = UnitDebuff("target",i);
		
		if( name == crhSpellName(59881) and isMine == "player") then -- Rake
			CatRotationHelperUpdateFrame(frames[RAKE], expTime);
			rakeupdate = true;
		elseif( name == crhSpellName(1079) and isMine == "player") then -- Rip
			CatRotationHelperUpdateFrame(frames[RIP], expTime);
			ripupdate = true;
		end
		
		i = i + 1;
	until (name == nil)

	if(rakeupdate ~= true) then
    	CatRotationFrameStopCounter(frames[RAKE]);
	end

	if(ripupdate ~= true) then
    	CatRotationFrameStopCounter(frames[RIP]);
	end
end

function CatRotationHelperCheckCatCooldown()
	local spellStart, spellDuration = GetSpellCooldown(crhSpellName(94391));  -- Tigers Fury
	if(spellStart ~= nil and spellDuration > 1.6) then
		CatRotationHelperUpdateFrame(frames[TIGERSFURY], spellStart + spellDuration)
	end
end

------------------------------
-- Bear - Main Frame Checks --
------------------------------

function CatRotationHelperMaulCheck()
	local frame = frames[MAUL]
	
	if(IsCurrentSpell(crhSpellName(54858))) then -- Maul
		if(frame.counting == false) then
			frame.counting = true;
			
			frame.icon:SetVertexColor(upcolor[1], upcolor[2], upcolor[3], upcolor[4]);
			frame.effectframe:Show();
			frame.effectframe.startTime = GetTime()
		end
	else
		if(frame.counting == true) then
			frame.counting = false;
			
			frame.icon:SetVertexColor(fadedcolor[1], fadedcolor[2], fadedcolor[3], fadedcolor[4]);	
			frame.effectframe:Show();
			frame.effectframe.startTime = GetTime()
		end
	end
end

function CatRotationHelperCheckBearDebuffs()	
	-- DemoRoar
	local name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(58279)); -- Demoralizing Shout (Warrior)
	if(name) then
		CatRotationHelperUpdateFrame(frames[DEMOROAR], expTime);
	else
    	name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(50256)); -- Demoralizing Roar (Druid)
    	if(name) then
        	CatRotationHelperUpdateFrame(frames[DEMOROAR], expTime);
        else
    		name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(26016)); -- Vindication (Paladin)
			if(name) then
        		CatRotationHelperUpdateFrame(frames[DEMOROAR], expTime);
    		else
				name,_,_,_,_,_,expTime = UnitDebuff("target", crhSpellName(21007)); -- Curse of Weakness (Warlock)
				if(name) then
					CatRotationHelperUpdateFrame(frames[DEMOROAR], expTime);
				else
					CatRotationFrameStopCounter(frames[DEMOROAR]);
				end
    		end
    	end
	end
	
	-- Lacerate: Check for own debuffs only	
	local i = 1;
	local name, stacks, expTime, isMine

	repeat
		name,_,_,stacks,_,_,expTime,isMine = UnitDebuff("target",i)
		
		if( name == crhSpellName(94384) and isMine == "player") then -- Lacerate
			CatRotationHelperUpdateFrame(frames[LACERATE], expTime);
			
			-- stop possible cp animation when lacerate is refreshed
			for i=1, #crhBearFrames do
				frames[crhBearFrames[i]].cpframe:SetAlpha(1)
				frames[crhBearFrames[i]].cpframe:SetScale(1)
			end
			
			-- setup lacerate warning
			CatRotationHelperLacerateCounter:Show()
			CatRotationHelperLacerateCounter.expTime = expTime

			-- set cp effects
			CatRotationHelperSetBearCP(stacks)

			return
		end
		
		i = i + 1;	
	until (name == nil)
	
	-- no Lacerate debuff found
    CatRotationFrameStopCounter(frames[LACERATE])
	CatRotationHelperLacerateCounter:Hide()
	CatRotationHelperSetBearCP(0)
end

function CatRotationHelperCheckBearCooldown()

	local spellStart, spellDuration = GetSpellCooldown(crhSpellName(16857));  -- Faerie Fire (Feral)
	if(spellStart ~= nil and spellDuration > 1.6) then
		CatRotationHelperUpdateFrame(frames[FAERIEFIRE], spellStart + spellDuration)
	end

	spellStart, spellDuration = GetSpellCooldown(crhSpellName(33878));  -- Mangle (Bear)
	if(spellStart ~= nil and spellDuration > 1.6) then
		CatRotationHelperUpdateFrame(frames[BEARMANGLE], spellStart + spellDuration)	
	elseif (spellStart ~= nil and spellDuration == 0) then
		--Berserker proc
		CatRotationFrameStopCounter(frames[BEARMANGLE]);
	end
	
	spellStart, spellDuration = GetSpellCooldown(crhSpellName(54858));  -- Maul
	if(spellStart ~= nil and spellDuration > 1.6) then
		CatRotationHelperUpdateFrame(frames[MAUL], spellStart + spellDuration)	
	end
end

function CatRotationHelperCheckBearBuffs()

	local i = 1;
	repeat
		local _, _, _, _, _, _, _, _, _, _, spellId = UnitBuff("player", i);
					
		if( spellId == 50334) then -- Berserk
			CatRotationFrameStopCounter(frames[BEARMANGLE]);
		end
		if(spellId == 54858) then
			CatRotationFrameStopCounter(frames[MAUL]);
		end
						
		i = i + 1;
	until (spellId == nil)
end

-- Check for Clearcast procs - Bear & Cat
function CatRotationHelperCheckClearcast()
	name,_,_,_,_,_,_ = UnitBuff("player", crhSpellName(16870)); -- Clearcast
	if(name and crhEnableClearcast) then
		if(not clearCast) then
			for i=1, #frames do
				frames[i].cpicon:SetTexture("Interface\\AddOns\\CatRotationHelper\\Cp-Blue.tga")
				frames[i].icon:SetTexture(blueTextures[i])
				frames[i].effectframe.effecticon:SetTexture(blueTextures[i])
				
				if(frames[i].hascp) then
					frames[i].countframe.durtext:SetTextColor(0.40, 0.70, 0.95);				
				else
					frames[i].countframe.durtext:SetTextColor(0.50, 0.85, 1.00);
				end
			end
			
			clearCast = true;
		end

	else
		if(clearCast) then
			for i=1,#frames do
				frames[i].cpicon:SetTexture("Interface\\AddOns\\CatRotationHelper\\Cp.tga")
				frames[i].icon:SetTexture(textures[i])
				frames[i].effectframe.effecticon:SetTexture(textures[i])
				
				if(frames[i].hascp) then
					frames[i].countframe.durtext:SetTextColor(0.90, 0.70, 0.00);				
				else
					frames[i].countframe.durtext:SetTextColor(1.00, 1.00, 0.00);
				end

			end
			
			clearCast = false;
		end
	end
end

-- Event Frame - Bear & Cat
function CatRotationHelperUpdateEvents()
	if(enemyTarget) then
		-- first, update eventList table
		if(inCatForm) then
		
			-- Berserk
			local spellStart, spellDuration = GetSpellCooldown(crhSpellName(50334));  -- Berserk
			local name, spellId, expTime
			if((spellStart == nil or spellDuration < 1.6) and crhShowCatBerserk) then
				eventList[1] = "Interface\\AddOns\\CatRotationHelper\\Berserk.tga"
				eventTimers[1] = nil
			else

				eventList[1] = nil
				eventTimers[1] = nil
				
				if(crhShowCatBerserk) then
					local i = 1;
					repeat
						_, _, _, _, _, _, expTime, _, _, _, spellId = UnitBuff("player", i);
						
						if( spellId == 50334) then -- Berserk
							eventList[1] = "Interface\\AddOns\\CatRotationHelper\\Berserk.tga"
							eventTimers[1] = expTime
						end
						
						i = i + 1;
					until (spellId == nil)
				end
			end
			
			-- Faerie Fire
			if(not crhTargetHasDebuff(crhSpellName(770)) and not crhTargetHasDebuff(crhSpellName(16857)) and crhShowCatFaerieFire) then
				eventList[2] = "Interface\\AddOns\\CatRotationHelper\\FaerieFire.tga"
				eventTimers[2] = nil
			else
				eventList[2] = nil
				eventTimers[2] = nil
			end

			-- Predator's Swiftness
			name,_,_,_,_,_,expTime = UnitBuff("player", crhSpellName(69369)); -- Predator's Swiftness
			if(name and crhShowPredatorsSwiftness) then
				eventList[3] = "Interface\\AddOns\\CatRotationHelper\\PredatoryStrikes.tga"
				eventTimers[3] = expTime
			else
				eventList[3] = nil
				eventTimers[3] = nil
			end

		elseif(inBearForm) then
		
			-- Berserk
			spellStart, spellDuration = GetSpellCooldown(crhSpellName(50334));  -- Berserk
			if((spellStart == nil or spellDuration < 1.6) and crhShowBearBerserk) then
				eventList[1] = "Interface\\AddOns\\CatRotationHelper\\Berserk.tga"
				eventTimers[1] = nil
			else

				eventList[1] = nil
				eventTimers[1] = nil
				if(crhShowBearBerserk) then
					local i = 1;
					repeat
						_, _, _, _, _, _, expTime, _, _, _, spellId = UnitBuff("player", i);
						
						if( spellId == 50334 ) then -- Berserk
							eventList[1] = "Interface\\AddOns\\CatRotationHelper\\Berserk.tga"
							eventTimers[1] = expTime
						end
						
						i = i + 1;
					until (spellId == nil)
				end
			end
			
			-- Survival Instincts
			spellStart, spellDuration = GetSpellCooldown(crhSpellName(61336));  -- Survival Instincts
			if((spellStart == nil or spellDuration < 1.6) and crhShowSurvivalInstincts) then
				eventList[2] = "Interface\\AddOns\\CatRotationHelper\\SurvivalInstincts.tga"
				eventTimers[2] = nil
			else
				-- add Survival Instincts with timer to event frame
				name,_,_,_,_,_,expTime = UnitBuff("player", crhSpellName(61336)); -- Survival Instincts
				if(name and crhShowSurvivalInstincts) then
					eventList[2] = "Interface\\AddOns\\CatRotationHelper\\SurvivalInstincts.tga"
					eventTimers[2] = expTime
				else
					eventList[2] = nil
					eventTimers[2] = nil
				end
			end

			
			-- Barkskin
			spellStart, spellDuration = GetSpellCooldown(crhSpellName(22812));  -- Barkskin
			if((spellStart == nil or spellDuration < 1.6) and crhShowBarkskin) then
				eventList[3] = "Interface\\AddOns\\CatRotationHelper\\Barkskin.tga"
				eventTimers[3] = nil
			else
				-- add Barkskin with timer to event frame
				name,_,_,_,_,_,expTime = UnitBuff("player", crhSpellName(22812)); -- Barkskin
				if(name and crhShowBarkskin) then
					eventList[3] = "Interface\\AddOns\\CatRotationHelper\\Barkskin.tga"
					eventTimers[3] = expTime
				else
					eventList[3] = nil
					eventTimers[3] = nil
				end
			end
	
		end
	
		-- second, fill event frames with information
		j = 1
		
		for i=1, #events do
			if(eventList[i] ~= nil) then
				if(not events[j]:IsVisible() or events[j].fading) then
					events[j]:SetScript("OnUpdate",CatRotationHelperEventFadeFunc)
					events[j]:Show()
					events[j].fading = false
					events[j].startTime = GetTime()		
				end
				
				events[j].icon:SetTexture(eventList[i])
				
				if(eventTimers[i] ~= nil) then
				    events[j].countframe.endTime = eventTimers[i]
					events[j].countframe:Show()
				else
					events[j].countframe:Hide()				
				end
				
				j = j + 1
			end
		end

		-- hide unused event frames
		while j <= #events do
			if(events[j]:IsVisible() and not events[j].fading) then
				events[j]:SetScript("OnUpdate",CatRotationHelperEventFadeFunc)
				events[j].fading = true
				events[j].startTime = GetTime()
			end
			
			j = j + 1
		end

	else -- no enemytarget, hide events
		for i=1, #events do
			if(events[i]:IsVisible() and not events[i].fading) then
				events[i]:SetScript("OnUpdate",CatRotationHelperEventFadeFunc)
				events[i].fading = true
				events[i].startTime = GetTime()
			end
		end
	end

end

-- OnLoad: Create Frames
function CatRotationHelperOnLoad(self)
	-- load addon on druids only
	local _,class = UnitClass("player")
	if(class == "DRUID") then
		self:SetScript("OnEvent", CatRotationHelperOnEvent)
	else
		return;
	end

	self:SetBackdropColor(0, 0, 0);
	self:RegisterForClicks("RightButtonUp")
	self:RegisterForDrag("LeftButton")
	self:SetClampedToScreen(true)

	
	local eventFrame = CatRotationHelperEvents
	eventFrame:SetBackdropColor(0, 0, 0);
	eventFrame:RegisterForClicks("RightButtonUp")
	eventFrame:RegisterForDrag("LeftButton")
	eventFrame:SetClampedToScreen(true)

	SlashCmdList["CRH"] = CatRotationHelperCommand;
	SLASH_CRH1 = "/crh";
	
	-- setup frames
	for i=1, #frames do
		local frame = frames[i]
		
		frame.parentFrame = CreateFrame("Frame", nil, UIParent);
		frame.parentFrame:SetWidth(30)
		frame.parentFrame:SetHeight(30)
		frame:SetPoint("CENTER", frame.parentFrame, CENTER, 0, 0);

		frame:SetFrameStrata("LOW");
		frame:SetWidth(30)
		frame:SetHeight(30)
		frame:Hide()
		frame.hascp = false
		frame.counting = false

		frame.cpframe = CreateFrame("Frame", nil, frame);
		frame.cpframe:SetFrameStrata("BACKGROUND");
		frame.cpframe:SetPoint("CENTER");
		frame.cpframe:SetWidth(34)
		frame.cpframe:SetHeight(34)
		frame.cpframe.startTime = nil;
		frame.cpframe:Hide();

		frame.cpicon = frame.cpframe:CreateTexture(nil,"BACKGROUND")
		frame.cpicon:SetTexture("Interface\\AddOns\\CatRotationHelper\\Cp.tga")
		frame.cpicon:SetAllPoints(frame.cpframe)
	
		frame.icon = frame:CreateTexture(nil,"ARTWORK")
		frame.icon:SetAllPoints(frame)
		frame.icon:SetVertexColor(fadedcolor[1], fadedcolor[2], fadedcolor[3], fadedcolor[4]);
		frame.icon:SetTexture(textures[i])

		-- buff fade/gain effects
		frame.effectframe = CreateFrame("Frame", nil, frame);
		frame.effectframe:SetPoint("CENTER");
		frame.effectframe:SetWidth(38)
		frame.effectframe:SetHeight(38)
		frame.effectframe:Hide();
		frame.effectframe:SetScript("OnUpdate", CatRotationFrameEffect)
		frame.effectframe.startTime = nil;

		frame.effectframe.effecticon = frame.effectframe:CreateTexture(nil,"ARTWORK")
		frame.effectframe.effecticon:SetTexture(textures[i])
		frame.effectframe.effecticon:SetAllPoints(frame.effectframe)
		frame.effectframe.effecticon:SetBlendMode("ADD");

		frame.countframe = CreateFrame("Frame", nil, frame);
		frame.countframe:SetScript("OnUpdate", CatRotationFrameCounter)
		frame.countframe:Hide();
		frame.countframe.endTime = nil;
		
		frame.countframe.durtext = frame.countframe:CreateFontString(nil, "OVERLAY", "CatRotationHelperDurText")
		frame.countframe.durtext:SetPoint("CENTER", frame, "CENTER", 0, 0);
	end
	
	-- setup events
	for i=1, #events do
		local event = events[i]
		event.parentFrame = CreateFrame("Frame", nil, UIParent);
		event.parentFrame:SetWidth(30)
		event.parentFrame:SetHeight(30)
		event:SetPoint("CENTER", event.parentFrame, CENTER, 0, 0);

		event:SetFrameStrata("LOW");
		event:SetWidth(30)
		event:SetHeight(30)
		event:Hide()
		event.fading = false
		event.startTime = nil

		event.icon = event:CreateTexture(nil,"ARTWORK")
		event.icon:SetAllPoints(event)
		event.icon:SetVertexColor(upcolor[1], upcolor[2], upcolor[3], upcolor[4]);

		event.countframe = CreateFrame("Frame", nil, event);
		event.countframe:SetScript("OnUpdate", CatRotationFrameEventCounter)
		event.countframe:Hide();
		event.countframe.endTime = nil;
		
		event.countframe.durtext = event.countframe:CreateFontString(nil, "OVERLAY", "CatRotationHelperDurText")
		event.countframe.durtext:SetPoint("CENTER", event, "CENTER", 0, 0);
	end
	
	self:RegisterEvent("UNIT_AURA");
	self:RegisterEvent("PLAYER_TARGET_CHANGED");
	self:RegisterEvent("UPDATE_SHAPESHIFT_FORM");
	self:RegisterEvent("ADDON_LOADED");
	self:RegisterEvent("UNIT_FACTION");
	self:RegisterEvent("SPELL_UPDATE_COOLDOWN");
	self:RegisterEvent("ACTIONBAR_UPDATE_STATE");
	
	-- power bar
	--self:RegisterEvent("UNIT_ATTACK_POWER")
	--self:RegisterEvent("UNIT_ATTACK_SPEED")
	--self:RegisterEvent("COMBAT_RATING_UPDATE")
end

-- Event Handling
function CatRotationHelperOnEvent (self, event, ...)
	arg1 = ...
	
	if(unlocked or crhRotateMode) then
		return
	end
	
	if(event == "UNIT_AURA") then
		if(enemyTarget) then
			if(inCatForm) then
				if(arg1 == "player") then
					CatRotationHelperCheckCatBuffs();
					CatRotationHelperCheckClearcast();
					CatRotationHelperUpdateEvents()
				elseif(arg1 == "target") then
					CatRotationHelperCheckCatDebuffs();
					CatRotationHelperUpdateEvents()
				end
			elseif(inBearForm) then
				if(arg1 == "target") then
					CatRotationHelperCheckBearDebuffs();
				elseif(arg1 == "player") then
					CatRotationHelperCheckBearBuffs()
					CatRotationHelperCheckBearCooldown(); --This is for procced reset of mangle
					CatRotationHelperCheckClearcast();
					CatRotationHelperUpdateEvents()
				end
			end
		end
		
		
	elseif(event == "ACTIONBAR_UPDATE_STATE") then
		if(inBearForm) then
			CatRotationHelperMaulCheck();
		end
		
	elseif(event == "UNIT_COMBO_POINTS") then
		if(arg1 == "player") then
			CatRotationHelperSetCatCP(GetComboPoints("player"))
		end
		
	elseif(event == "SPELL_UPDATE_COOLDOWN") then
		if(enemyTarget) then
			if(inBearForm) then
				CatRotationHelperCheckBearCooldown()
				CatRotationHelperUpdateEvents()
			elseif(inCatForm) then
				CatRotationHelperCheckCatCooldown()
				CatRotationHelperUpdateEvents()
			end
		end

	elseif(event == "UPDATE_SHAPESHIFT_FORM") then	
			
		if(GetShapeshiftForm() == 3 and crhShowCat) then -- switch to cat form
			if(inBearForm) then CatRotationHelperHideAll() end
			inBearForm = false
			inCatForm = true	

			if (enemyTarget) then
				CatRotationHelperShowCat();
				CatRotationHelperCheckCatBuffs();
				CatRotationHelperCheckClearcast();
				CatRotationHelperCheckCatDebuffs();
				CatRotationHelperCheckCatCooldown()
				CatRotationHelperSetCatCP(GetComboPoints("player"));
				CatRotationHelperUpdateEvents()
			end
				
			CatRotationHelperCheckClearcast();
		elseif(GetShapeshiftForm() == 1 and crhShowBear) then -- switch to bear form			
			if(inCatForm) then CatRotationHelperHideAll() end
			inCatForm = false
			inBearForm = true

			if (enemyTarget) then
				CatRotationHelperShowBear();
				CatRotationHelperCheckBearBuffs()
				CatRotationHelperCheckClearcast();
				CatRotationHelperCheckBearDebuffs();
				CatRotationHelperCheckBearCooldown()
				CatRotationHelperUpdateEvents()
			end		
			
			CatRotationHelperCheckClearcast();
		else -- caster or other form
			CatRotationHelperHideAll();
			inCatForm = false
 			inBearForm = false
		end
		

	elseif(event == "PLAYER_TARGET_CHANGED" or (event == "UNIT_FACTION" and arg1 == "target")) then
		-- checking UNIT_FACTION so starting a duel behaves like changing target
	
		if(UnitExists("target") and UnitCanAttack("player", "target") and not UnitIsDead("target")) then
			enemyTarget = true

        	if (inCatForm) then
        		CatRotationHelperShowCat();
        		CatRotationHelperCheckCatBuffs();
				CatRotationHelperCheckClearcast();
        		CatRotationHelperCheckCatDebuffs();
				CatRotationHelperCheckCatCooldown()
				CatRotationHelperSetCatCP(GetComboPoints("player"))
				CatRotationHelperUpdateEvents()
        	elseif(inBearForm) then
        		CatRotationHelperShowBear();	
				CatRotationHelperCheckBearBuffs()
				CatRotationHelperCheckClearcast();				
        		CatRotationHelperCheckBearDebuffs();
				CatRotationHelperCheckBearCooldown();
				CatRotationHelperUpdateEvents()
			end
		else
        	enemyTarget = false
        	CatRotationHelperHideAll();
			CatRotationHelperUpdateEvents()
		end
	
	--elseif(event == "UNIT_ATTACK_POWER" or event == "UNIT_ATTACK_SPEED" or event == "COMBAT_RATING_UPDATE") then
	
		
	elseif(event == "ADDON_LOADED" and arg1 == "CatRotationHelper") then
		CatRotationFrameSetMainScale()
		CatRotationFrameSetEventScale()
		CatRotationFrameSetMainStyle()
		CatRotationFrameSetEventStyle()
		
		if(crhCp) then
			self:RegisterEvent("UNIT_COMBO_POINTS");
		end
		
		CatRotationHelperUpdateEverything()
	end
end

-----------------------
-- Counter Functions --
-----------------------

function CatRotationFrameCounter(self)
	local time = self.endTime - GetTime();

	if(time <= 0) then
		CatRotationFrameStopCounter(self:GetParent());
	else
		self.durtext:SetText(CatRotationHelperFormatTime(time));
	end
end

function CatRotationFrameEventCounter(self)
	local time = self.endTime - GetTime();

	if(time <= 0) then
		self:Hide()
		self.durtext:SetText("")
	else
		self.durtext:SetText(CatRotationHelperFormatTime(time));
	end
end

-- combo point animation when lacerate is about to expire
function CatRotationHelperLacerateCounterFunc(self)
	local remaining = self.expTime - GetTime()
	
	if(remaining > 3.0) then
		return
	elseif(remaining <= 0) then
		self:Hide()
		return
	end

	local t = mod(remaining,1)

	if(t <= 0.5) then
		for i=1, #crhBearFrames do
			frames[crhBearFrames[i]].cpframe:SetAlpha(1.0-t)
			frames[crhBearFrames[i]].cpframe:SetScale(1.0+0.3*t)
		end
	else
		for i=1, #crhBearFrames do
			frames[crhBearFrames[i]].cpframe:SetAlpha(t)
			frames[crhBearFrames[i]].cpframe:SetScale(1.3-0.3*t)
		end
	end
end

----------------------
-- Effect Functions --
----------------------

-- fade main frame in/out
function CatRotationHelperFadeFunc(self)
	local elapsed = GetTime() - self.startTime;

	if(elapsed > 0.4) then
		self:Hide();

		if(self.fading) then
			for i=1, #frames do
				frames[i]:Hide();
			end
		end
	end

	if(self.fading) then
		for i=1, #frames do
			frames[i]:SetAlpha(1-elapsed*2.5);
		end
	else
		for i=1, #frames do
			frames[i]:SetAlpha(elapsed*2.5);
		end	
	end
end

-- fade single events in/out
function CatRotationHelperEventFadeFunc(self)
	local elapsed = GetTime() - self.startTime;

	if(elapsed > 0.4) then
		if(self.fading) then
			self:Hide()
		else
			self:SetScript("OnUpdate", nil);
		end
	end

	if(self.fading) then
		self:SetAlpha(1-elapsed*2.5);
	else
		self:SetAlpha(elapsed*2.5);
	end
end

-- fade single frames in/out
function CatRotationFrameEffect(self)
	local elapsed = GetTime() - self.startTime;

	if(elapsed >= 0.5) then
		self:Hide();
		return;
	end

	if(not self:GetParent().counting) then
		elapsed = 0.5 - elapsed
	end

	self:SetScale(1-elapsed*0.3)

	if(elapsed >= 0.25) then
		self:SetAlpha(1.0-elapsed*2)
	else
		self:SetAlpha(elapsed*2)
	end
end

-- fade cps in/out
function CatRotationHelperCpEffect(self)
	local elapsed = GetTime() - self.startTime;

	if(elapsed >= 0.4) then
		if(self.reverse) then
			self:Hide();
		else
			self:SetScale(1)
			self:SetAlpha(1)
			self:SetScript("OnUpdate",nil)
		end
		return;
	end
	
	if(self.reverse) then
		elapsed = 0.4-elapsed
	end
	
	self:SetScale(1.2-elapsed*0.5)
	self:SetAlpha(elapsed*2.5)
end
